03 基础系统调用
进程管理
Linux 创建一个新的进程,需要一个老的进程调用 fork 来实现,老的进程叫作父进程(Parent Process),新的进程叫作子进程(Child Process)。
当父进程调用 fork 创建进程,子进程将各个子系统为父进程创建的数据结构也全部拷贝一份,程序代码也拷贝过来。
fork 系统调用,如果当前进程是子进程就返回 0,如果当前进程是父进程就返回子进程的进程号。父进程接着做原来应该做的事,子进程请求另一个系统调用execve来执行另一个程序。
系统调用waitpid通过子进程的进程号获取子进程是否运行完以及成功与否。
内存管理
操作系统中,每个进程都有自己的内存,互相之间不干扰,有独立的进程内存空间。
进程的内存空间放程序代码的这部分称为代码段(Code Segment)。放进程运行中产生数据的部分称为数据段(Data Segment)。
局部变量在当前函数执行时起作用,进入另一个函数时变量就释放;
动态分配的较长时间保存,指明才销毁的称为堆(Heap)。
在堆里面分配内存的系统调用,当分配的内存数量比较小时用 brk,和原来的堆的数据连在一起。当分配的内存数量比较大时用 mmap,重新划分一块区域。
文件管理
对文件操作的六个系统调用:
- creat 创建文件
- open 打开文件
- close 关闭文件
- lseek 跳到文件的某个位置
- read 对文件内容进行读
- write 对文件内容进行写
Linux 为每个文件分配一个文件描述符(File Descriptor),可以使用系统调用查看或干预进程运行的方方面面。
信号处理
- CTRL+C 中止退出正在执行的命令
- 非法访问内存
- 硬件故障
- 用户进程通过kill函数将一个用户信号发送给另一个进程
进程间通信
消息队列(Message Queue):内核里维护的消息队列。
msgget创建一个新的队列,msgsnd将消息发送到消息队列,消息接收方使用msgrcv从队列中取消息。
共享内存:两个进程共享一份数据。
通过shmget创建一个共享内存块,通过shmat将共享内存映射到自己的内存空间进行读写。通过信号量的机制 Semaphore 让不同的进程够排他地访问。
网络通信
TCP/IP 网络协议栈:不同机器通过网络相互通信要遵循相同的网络协议。
Linux 内核实现了网络协议栈,网络服务通过套接字 Socket 来提供服务。
通过 Socket 系统调用建立 Socket,Socket 也是一个文件,也有一个文件描述符,也可以通过读写函数进行通信。
Glibc
Linux 下使用的开源的标准 C 库,包含字符串处理、数学运算等用户态服务,和操作系统提供的系统服务等系统调用的封装。